package com.uam.core.scheduler;

import com.alibaba.fastjson.JSONArray;
import com.uam.core.business.OperationDbBusiness;
import com.uam.core.business.ParentBusiness;
import com.uam.core.business.help.TestInfo;
import com.uam.core.cache.PointCacheConfig;
import com.uam.core.dao.elasticsearch.ElasticsearchDao;
import com.uam.core.entity.PointInfoData;
import com.uam.core.entity.constant.RedisConstants;
import com.uam.core.entity.enums.ElasticsearchIndices;
import com.uam.core.entity.model.ElasticsearchQueryResult;
import com.uam.core.entity.model.RedisAltitudeInfo;
import com.uam.core.entity.uitls.ZipUtil;
import com.uam.core.tool.DateUtils;
import com.uam.core.tool.GeoTools;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 冲突解决
 * @author hegaunglong
 */
@Component
public class ConflictResolution  extends ParentBusiness {
    @Autowired
    private PointCacheConfig pointCacheConfig;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Autowired
    OperationDbBusiness operationDbBusiness;

    @Autowired
    ElasticsearchDao elasticsearchDao;



    /**
     *
     * @author hegaunglong
     * @date 2024/7/19
     * @param takId 本次检测的任务id
     * @param sourceTaskId 被检测的任务id
     * @param type 类型
     * @param distance 安全距离
     * @param newPoint 当前位置点
     * @param sourcePoint 对冲飞机位置
     * @param sourcePointInfo 对冲飞机轨迹数据集合
     * @param newPointInfo 当前飞机轨迹数据集合
     * @return void
     */
    public void  conflictHandling(Integer takId, Integer sourceTaskId, String type, double distance, PointInfoData newPoint, PointInfoData sourcePoint, List<PointInfoData> sourcePointInfo, List<PointInfoData> newPointInfo) throws IOException {
         Coordinate coordinate=     new Coordinate(newPoint.getLon(),newPoint.getLat());

        Polygon pBuffer = this.lineBuffer(new Coordinate[]{coordinate, new Coordinate(sourcePoint.getLon(),sourcePoint.getLat())}, newPoint.getBuffer());

        //查找位置：
        int index= newPoint.getIndex()-1;
        List<PointInfoData> dataList=new ArrayList<>( pointCacheConfig.get(takId).values());
        List<PointInfoData> dataLineList=dataList.subList(index,dataList.size()-3);
        LineString lineString=  dataInfoToLineString(dataLineList);
        JSONArray geometryPoint = TestInfo.test(lineString, pBuffer);
        if(geometryPoint == null){
            return;
        }

        JSONArray endPointA= geometryPoint.getJSONArray(geometryPoint.size()-1);

        String dataPointAll=redisTemplate.opsForValue().get(RedisConstants.ROUTE_POINTS+takId).toString();
        JSONArray jsonArrayCache=JSONArray.parseArray(ZipUtil.uncompressBase64(dataPointAll));
        JSONArray jsonArrayNew=new JSONArray(1024);


        for (int i = 0; i < index; i++){
            JSONArray jsonArray= jsonArrayCache.getJSONArray(i);
            jsonArray.remove(3);
            if(jsonArray.size() ==4) {
                jsonArray.remove(3);
            }
            jsonArrayNew.add(jsonArray);
        }
        jsonArrayNew.addAll(geometryPoint);


        int row=jsonArrayCache.size()-1;
        for (int i = getEndIndex(jsonArrayCache,index,endPointA); i < row; i++){
            JSONArray jsonArray= jsonArrayCache.getJSONArray(i);
            jsonArray.remove(3);
            if(jsonArray.size() ==4) {
                jsonArray.remove(3);
            }
            jsonArrayNew.add(jsonArray);
        }
        RedisAltitudeInfo redisAltitudeInfo= ( RedisAltitudeInfo)redisTemplate.opsForValue().get(RedisConstants.TASK_MODEL_INFO+takId);
        //重新计算时间
        getHistoryTime(jsonArrayNew, redisAltitudeInfo.getAircraftModel().getSpeed(), redisAltitudeInfo.getTaskModel(), 0, true);
        long deleted=elasticsearchDao.deleteDocumentByName(ElasticsearchIndices.ROUTE_COMPONENT_INDEX.getName(), ElasticsearchQueryResult.CommonFields.TASK_ID.getName() ,takId);
//        System.out.println(deleted);


        operationDbBusiness.setUpdataDb(jsonArrayNew,redisAltitudeInfo);

//        System.out.println("--->"+JSONArray.toJSONString(jsonArrayNew));
        PointInfoDo pointInfoDo = PointInfoScheduler.getPointInfoDo(takId);
        pointInfoDo.getCollisionDo(sourceTaskId).setStatus(1);


        PointInfoDo pointInfoDoSource = PointInfoScheduler.getPointInfoDo(sourceTaskId);
        if(pointInfoDoSource != null && pointInfoDoSource.getCollisionDo(takId) != null) {
            pointInfoDoSource.getCollisionDo(takId).setStatus(1);
        }
    }

    public int getEndIndex(JSONArray jsonArray,int startIndex,JSONArray endPointA){
        double minDistance = Double.MAX_VALUE;
        Coordinate e = new Coordinate(endPointA.getDouble(0),endPointA.getDouble(1));
        int index = -1;
        for (int i = startIndex+2; i < jsonArray.size(); i++){
           JSONArray rowJson= jsonArray.getJSONArray(i);
            Coordinate s = new Coordinate(rowJson.getDouble(0),rowJson.getDouble(1));
            double distance= s.distance(e);
            if (distance < minDistance) {
                minDistance = distance;
                index = i;
            }
        }
        return index+1;
    }
}
